package com.example.yilanchatserver.business.freechat;

import com.alibaba.fastjson.JSONObject;
import com.example.yilanchatserver.business.freechat.service.dto.FreeChatDTO;
import com.example.yilanchatserver.business.freechat.service.dto.FreeChatPromptDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClientResponseException;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import javax.annotation.PostConstruct;
import java.util.*;

@Slf4j
@Component
public class ZhiPuPromptWebClient {

    private WebClient webClient;


    @Value("${wudao.url.streamPrompt}")
    private String CHAT_API;

    @Value("${wudao.url.knowledge.chat}")
    private String knowledgeChat;

    @Value("${wudao.url.knowledge.sse}")
    private String knowledgeSSE;

    @Value("${wudao.url.knowledge.baseline}")
    private String knowledgeBase;


    /**
     * dev采用代理访问
     */
    @PostConstruct
    public void init() {
        initProd();
    }





    public void initProd() {
        log.info("initProd");
        this.webClient = WebClient.builder()
                .defaultHeader(HttpHeaders.CONTENT_TYPE, "application/json")
                .build();
    }


    public Flux<String> getChatResponse(FreeChatPromptDTO freeChatDTO, String authToken, Integer maxTokens, Double temperature, Double topP) {

        JSONObject talkerParams = new JSONObject();
        talkerParams.put("temperature", temperature);
        talkerParams.put("top_p", topP);
        String preUuid = UUID.randomUUID().toString();
        talkerParams.put("requestTaskNo",preUuid);

        List<String> tmp =  new ArrayList<>();

        // 预先设置
//        String proQ = "你是元宇宙展厅的一位数字人员工，现在对你要求如下：\n1.需要在科技展厅面对用户的问题给出严肃、简洁、准确的回答。\n2.回答不超过200个汉字。\n3.如果你确实不知道，也请如实给出不知道的原因，并婉转地表达不知道的意思。\n请扮演上述角色。如果明白，请回答“明白”，无需回答其他信息。";
////            String proQ = "给你的要求如下：你的所有回答不得超过50字。如果明白，请回答“明白”";
//        String proA = "明白。";

        Integer totalNum = 0;

        if(freeChatDTO.getTalkList()!=null && freeChatDTO.getTalkList().size()!=0){
            talkerParams.put("prompt", freeChatDTO.getTalkList().get(freeChatDTO.getTalkList().size() - 1).get("text"));
            for(int i = freeChatDTO.getTalkList().size() - 2;i >= 0;i = i - 2){
                if(i % 2 != 1){ //必须为偶数
                    throw new BusinessException(BusinessErrorCodes.QAPAIRS_ERROR);
                }
                if(freeChatDTO.getTalkList().get(i-1).get("text") == null || freeChatDTO.getTalkList().get(i).get("text") == null){
                    continue;
                }
                Integer num = freeChatDTO.getTalkList().get(i-1).get("text").length() + freeChatDTO.getTalkList().get(i).get("text").length();
                if(totalNum + num > 500){ //控制token，小于等于500（不含初始QA对）
                    break;
                }
                totalNum += num;
                tmp.add(freeChatDTO.getTalkList().get(i).get("text"));
                tmp.add(freeChatDTO.getTalkList().get(i-1).get("text"));

            }
        }
        else{
            throw new BusinessException(BusinessErrorCodes.QAPAIRS_ERROR);
        }
        if(freeChatDTO.getPrompt()!=null && freeChatDTO.getPrompt().size()!=0){
            for(int i = freeChatDTO.getPrompt().size() - 1;i >= 0;i = i - 2){
                if(i % 2 != 1){ //必须为偶数
                    throw new BusinessException(BusinessErrorCodes.QAPAIRS_ERROR);
                }
                if(freeChatDTO.getPrompt().get(i-1).get("text") == null || freeChatDTO.getPrompt().get(i).get("text") == null){
                    continue;
                }
                Integer num = freeChatDTO.getPrompt().get(i-1).get("text").length() + freeChatDTO.getPrompt().get(i).get("text").length();

                totalNum += num;
                tmp.add(freeChatDTO.getPrompt().get(i).get("text"));
                tmp.add(freeChatDTO.getPrompt().get(i-1).get("text"));

            }
        }
        Collections.reverse(tmp);

        talkerParams.put("history", tmp);
        System.out.println(preUuid);

//        List<Map<String, String>> qaPairs = new ArrayList<>();
//
//        if(freeChatDTO.getPrompt() != null){
//            for(int i = 0;i < freeChatDTO.getPrompt().size();i++){
//
//                Map<String, String> tmp =  freeChatDTO.getPrompt().get(i);
////                if(Objects.equals(tmp.get("talker"), "bot")){
////                    tmp.put("talker", "assistant");
////                }
////                tmp.put("role", tmp.remove("talker"));
////                tmp.put("content", tmp.remove("text"));
//                qaPairs.add(tmp);
//            }
//        }
//
//
//        for(int i = 0;i < freeChatDTO.getTalkList().size();i++){
//
//            Map<String, String> tmp =  freeChatDTO.getTalkList().get(i);
////            if(Objects.equals(tmp.get("talker"), "bot")){
////                tmp.put("talker", "assistant");
////            }
////            tmp.put("role", tmp.remove("talker"));
////            tmp.put("content", tmp.remove("text"));
//            qaPairs.add(tmp);
//        }
//
//
//
//        talkerParams.put("prompt", qaPairs);
//        System.out.println(preUuid);
        log.info("强制执行有情感问答");
        return webClient.post()
                .uri(CHAT_API)
                .header(HttpHeaders.AUTHORIZATION, "Bearer " + authToken)
                .bodyValue(talkerParams.toJSONString())
                .retrieve()
                .bodyToFlux(String.class)
                .onErrorResume(WebClientResponseException.class, ex -> {
                    HttpStatus status = ex.getStatusCode();
                    String res = ex.getResponseBodyAsString();
                    log.error("OpenAI API error: {} {}", status, res);
                    return Mono.error(new RuntimeException(res));
                });

//        else{
//            throw new Exception("不允许同时开启情感与知识库");
////            talkerParams.remove("top_p");
////            talkerParams.remove("temperature");
////            talkerParams.put("incremental", false); // 全量返回
////            talkerParams.put("prompt", tmp);
////            return webClient.post()
////                    .uri(knowledgeBase+knowledgeChat+freeChatDTO.getRobotId()+knowledgeSSE)
////                    .header(HttpHeaders.AUTHORIZATION, "Bearer " + authToken)
////                    .bodyValue(talkerParams.toJSONString())
////                    .retrieve()
////                    .bodyToFlux(String.class)
////                    .onErrorResume(WebClientResponseException.class, ex -> {
////                        HttpStatus status = ex.getStatusCode();
////                        String res = ex.getResponseBodyAsString();
////                        log.error("OpenAI API error: {} {}", status, res);
////                        return Mono.error(new RuntimeException(res));
////                    });
//            }
        }


    }

